package com.one.tank;

import java.awt.*;
import java.util.Vector;

//坦克父类
public class Tank {
    //坦克类别常量：0-我方 1-敌方
    public final static int TANK_TYPE_OUR = 0;
    public final static int TANK_TYPE_ENEMY = 1;
    //坦克的颜色 我方坦克和敌方坦克
    public final static Color OUR_TANK_COLOR = Color.YELLOW;
    public final static Color ENEMY_TANK_COLOR = Color.CYAN;
    //设置坦克的朝向
    public final static int UP = 0;
    public final static int DOWN = 1;
    public final static int LEFT = 2;
    public final static int RIGHT = 3;
    //坦克状态常量：0-停止 1-运行
    public final static int TANK_STOP = 0;
    public final static int TANK_GO = 1;
    //坦克最大血量值
    public final static int TANK_MAX_BLOOD = 100;
    //坦克尺寸常量
    public final static int TANK_WIDTH = 40;
    public final static int TANK_HEIGHT = 40;
    //坦克轮子尺寸
    public final static int TANK_WHEEL_WIDTH = 7;
    public final static int TANK_WHEEL_HEIGHT = 30;
    //当前坦克的方向-->默认坦克朝上
    private int direction = UP;
    //坦克的位置
    private int x;
    private int y;
    //坦克速度
    private int speed = 8;
    //坦克血量
    private int blood = TANK_MAX_BLOOD;
    //坦克类别
    private int type = TANK_TYPE_OUR;
    //坦克状态
    private int state = TANK_STOP;
    //子弹池-->考虑线程安全用Vector，没用ArrayList
    private Vector<Bullet> bullets = new Vector<>();
    //上次射击时间（用来设置2次射击最小时间间隔，禁止连续射击）
    private long lastFireTime = System.currentTimeMillis();

    public Tank(int x, int y) {
        this.x = x;
        this.y = y;
    }

    /**
     * 构造函数
     *
     * @param type      坦克类别
     * @param x         坦克左上角X坐标
     * @param y         坦克左上角Y坐标
     * @param direction 坦克方向
     */
    public Tank(int type, int x, int y, int direction) {
        this.type = type;
        this.x = x;
        this.y = y;
        this.direction = direction;
    }

    //画坦克-->确定坦克的像素大小40*40
    public void drawTank(Graphics g) {
        //设置颜色
        g.setColor(OUR_TANK_COLOR);
        //设置底色-->当坦克处于非移动状态时，填充底色可以模拟坦克的实际外形
        //false表示矩形填充时不会检测到图像的边缘
        g.fill3DRect(this.x, this.y, TANK_WIDTH, 3, false);
        //绘制血条
        g.setColor(Color.RED);
        //血量(计算宽度时由于都是int类型，因此除法是放到最后计算的，防止出现结果为0的问题[int取整了])
        g.fill3DRect(this.x, this.y, (blood * TANK_WIDTH) / TANK_MAX_BLOOD, 3, false);
        //绘制血条的边框
        g.setColor(Color.WHITE);
        g.draw3DRect(this.x, this.y, TANK_WIDTH, 3, false);
        //坦克到血条的高度
        int tankToBloodHeight = 5;
        //绘制坦克的颜色
        if (this.type == TANK_TYPE_OUR) {
            //我方坦克
            g.setColor(OUR_TANK_COLOR);
        } else if (this.type == TANK_TYPE_ENEMY) {
            //敌方坦克
            g.setColor(ENEMY_TANK_COLOR);
        }
        //绘制四周的虚线-->绘制小圆点(1个像素大小)-->for循环
        for (int i = 0; i <= 10; i++) {
            //在左右两侧的点x不变，y变
            //绘制左边的点
            g.drawOval(x - 1, y + 4 * i - 1, 1, 1);
            //绘制右边的点
            g.drawOval(x + TANK_WIDTH - 1, y + 4 * i - 1, 1, 1);
            //绘制上边的点
            /*if (i == 0) {
                //第一行
                for (int j = 0; j < 9; j++) {
                    g.drawOval(x + 4 - 1 + 4 * j, y - 1, 1, 1);
                }
            }
            //绘制下边的点
            if (i == 10) {
                //最后一行
                for (int j = 0; j < 9; j++) {
                    g.drawOval(x + 4 - 1 + 4 * j, y + 40 - 1, 1, 1);
                }
            }*/
            //上面的点或者下面的点
            /*if (i == 0 || i == 10) {
                int j = 1;
                while (j < 10) {
                    g.drawOval(x - 1 + 4 * j, y - 1 + 4 * i, 1, 1);
                    j++;
                }
            }*/
            if (i < 10) {
                g.drawOval(x + 4 * i - 1, y + TANK_HEIGHT - 1, 1, 1);
            }
        }
        //根据方向来绘制对应方向的坦克
        switch (direction) {
            //朝上的坦克
            case UP:
                //绘制左侧的轮子-->绘制出3D效果
                g.fill3DRect(this.x + tankToBloodHeight, this.y + tankToBloodHeight,
                        TANK_WHEEL_WIDTH, TANK_WHEEL_HEIGHT, false);
                //绘制右侧的轮子
                g.fill3DRect(x + TANK_WIDTH - tankToBloodHeight - TANK_WHEEL_WIDTH, y + tankToBloodHeight,
                        TANK_WHEEL_WIDTH, TANK_WHEEL_HEIGHT, false);
                //绘制坦克中间主体-->驾驶室
                g.fill3DRect(x + tankToBloodHeight + TANK_WHEEL_WIDTH, y + tankToBloodHeight + TANK_WHEEL_WIDTH,
                        TANK_WHEEL_HEIGHT - TANK_WHEEL_WIDTH * 2, TANK_WHEEL_HEIGHT - TANK_WHEEL_WIDTH * 2, false);
                //绘制中间的炮台-->设置一些小偏差
                g.fillOval(x + tankToBloodHeight + TANK_WHEEL_WIDTH + 2, y + tankToBloodHeight + TANK_WHEEL_WIDTH + 2,
                        TANK_WHEEL_HEIGHT - TANK_WHEEL_WIDTH * 2 - 4, TANK_WHEEL_HEIGHT - TANK_WHEEL_WIDTH * 2 - 4);
                //绘制炮筒
                g.fill3DRect(x + TANK_WIDTH / 2 - 2, y + tankToBloodHeight,
                        4, TANK_HEIGHT / 2 - tankToBloodHeight, false);
                break;
            //朝下的坦克
            case DOWN:
                //驾驶室
                g.fill3DRect(x + tankToBloodHeight + TANK_WHEEL_WIDTH, y + tankToBloodHeight + TANK_WHEEL_WIDTH,
                        TANK_WHEEL_HEIGHT - TANK_WHEEL_WIDTH * 2, TANK_WHEEL_HEIGHT - TANK_WHEEL_WIDTH * 2, false);
                //炮台
                g.fillOval(x + tankToBloodHeight + TANK_WHEEL_WIDTH + 2, y + tankToBloodHeight + TANK_WHEEL_WIDTH + 2,
                        TANK_WHEEL_HEIGHT - TANK_WHEEL_WIDTH * 2 - 4, TANK_WHEEL_HEIGHT - TANK_WHEEL_WIDTH * 2 - 4);
                //左边轮子
                g.fill3DRect(x + tankToBloodHeight, y + tankToBloodHeight,
                        TANK_WHEEL_WIDTH, TANK_WHEEL_HEIGHT, false);
                //右边轮子
                g.fill3DRect(x + TANK_WIDTH - tankToBloodHeight - TANK_WHEEL_WIDTH, y + tankToBloodHeight,
                        TANK_WHEEL_WIDTH, TANK_WHEEL_HEIGHT, false);
                //炮筒
                g.fill3DRect(x + TANK_WIDTH / 2 - 2, y + TANK_HEIGHT / 2 - 2,
                        4, TANK_WIDTH / 2 - tankToBloodHeight, false);
                break;
            //朝左的坦克
            case LEFT:
                g.fill3DRect(x + tankToBloodHeight + TANK_WHEEL_WIDTH, y + tankToBloodHeight + TANK_WHEEL_WIDTH,
                        TANK_WHEEL_HEIGHT - TANK_WHEEL_WIDTH * 2, TANK_WHEEL_HEIGHT - TANK_WHEEL_WIDTH * 2, false);
                g.fillOval(x + tankToBloodHeight + TANK_WHEEL_WIDTH + 2, y + tankToBloodHeight + TANK_WHEEL_WIDTH + 2,
                        TANK_WHEEL_HEIGHT - TANK_WHEEL_WIDTH * 2 - 4, TANK_WHEEL_HEIGHT - TANK_WHEEL_WIDTH * 2 - 4);
                g.fill3DRect(x + tankToBloodHeight, y + tankToBloodHeight,
                        TANK_WHEEL_HEIGHT, TANK_WHEEL_WIDTH, false);
                g.fill3DRect(x + tankToBloodHeight, y + TANK_HEIGHT - tankToBloodHeight - TANK_WHEEL_WIDTH,
                        TANK_WHEEL_HEIGHT, TANK_WHEEL_WIDTH, false);
                //绘制炮筒
                g.fill3DRect(x + tankToBloodHeight, y + TANK_HEIGHT - tankToBloodHeight - TANK_WHEEL_WIDTH - tankToBloodHeight * 2,
                        (TANK_HEIGHT - tankToBloodHeight * 2) / 2, 4, false);
                break;
            //朝右的坦克
            case RIGHT:
                g.fill3DRect(x + tankToBloodHeight + TANK_WHEEL_WIDTH, y + tankToBloodHeight + TANK_WHEEL_WIDTH,
                        TANK_WHEEL_HEIGHT - TANK_WHEEL_WIDTH * 2, TANK_WHEEL_HEIGHT - TANK_WHEEL_WIDTH * 2, false);
                g.fillOval(x + tankToBloodHeight + TANK_WHEEL_WIDTH + 2, y + tankToBloodHeight + TANK_WHEEL_WIDTH + 2,
                        TANK_WHEEL_HEIGHT - TANK_WHEEL_WIDTH * 2 - 4, TANK_WHEEL_HEIGHT - TANK_WHEEL_WIDTH * 2 - 4);
                g.fill3DRect(x + tankToBloodHeight, y + tankToBloodHeight,
                        TANK_WHEEL_HEIGHT, TANK_WHEEL_WIDTH, false);
                g.fill3DRect(x + tankToBloodHeight, y + TANK_HEIGHT - tankToBloodHeight - TANK_WHEEL_WIDTH,
                        TANK_WHEEL_HEIGHT, TANK_WHEEL_WIDTH, false);
                //绘制炮筒
                g.fill3DRect(x + TANK_WIDTH - tankToBloodHeight - TANK_WHEEL_WIDTH - tankToBloodHeight * 2,
                        y + TANK_HEIGHT - tankToBloodHeight - TANK_WHEEL_WIDTH - tankToBloodHeight * 2,
                        (TANK_WIDTH - tankToBloodHeight * 2) / 2, 4, false);
                break;
        }
    }

    /**
     * 坦克移动
     *
     * @param direction 移动方向
     */
    public void move(int direction) {
        //如果按键和坦克的方向是同向的，直接做移动即可。如果不是同方向的，做坦克方向的调转
        //坦克移动--没有碰撞，可以移动
        if(this.direction==direction) {
            //方向相同，加速前进（要判断边界及是否碰撞到别的对象）
            if (!GameLogic.getInstance().tankMoveCollide(this)) {
                switch (direction) {
                    case UP:
                        this.y -= this.speed;
                        break;
                    case RIGHT:
                        this.x += this.speed;
                        break;
                    case DOWN:
                        this.y += this.speed;
                        break;
                    case LEFT:
                        this.x -= this.speed;
                        break;

                }
                //System.out.println("坦克坐标位置：" + "[" + x + "," + y + "]");
            }
        }
        //方向不同，仅调整方向不前进
        else {
            //坦克调转方向
            this.direction = direction;
        }
    }
    //坦克射击
    public void fire(){
        //禁止连续射击
        long curFireTime = System.currentTimeMillis();
        //2发/秒
        if((curFireTime -this.lastFireTime)>=500){
            this.lastFireTime=curFireTime;
        }
        else{
            return;
        }
        //在子弹池中寻找空闲的子弹
        Bullet bullet = null;
        for(int i=0;i<bullets.size();i++){
            Bullet tempBullet = bullets.get(i);
            if(tempBullet.getState()==Bullet.BULLET_STATE_FREE){
                bullet=tempBullet;
                break;
            }
        }
        //没有找到空闲子弹就增加一个
        if(bullet==null){
            bullet=new Bullet(this);
            bullets.add(bullet);
        }
        //设置子弹的位置
        switch(this.direction){
            case UP:
                bullet.setPosition(this.x + TANK_WIDTH/2 - bullet.getWidth()/2,this.y - bullet.getHeight(),this.direction);
                break;
            case RIGHT:
                bullet.setPosition(this.x + TANK_WIDTH,this.y + TANK_HEIGHT/2 - bullet.getHeight()/2,this.direction);
                break;
            case DOWN:
                bullet.setPosition(this.x + TANK_WIDTH/2 - bullet.getWidth()/2,this.y + TANK_HEIGHT,this.direction);
                break;
            case LEFT:
                bullet.setPosition(this.x - bullet.getWidth(),this.y + TANK_HEIGHT/2 - bullet.getHeight()/2,this.direction);
                break;
        }
        //让子弹飞一会
        bullet.fly();
    }
    //计算坦克受到的伤害
    public void hurt(Bullet bullet){
        this.blood-=bullet.getAttack();
        if(this.blood<0){
            this.blood=0;
        }
    }
    //判断坦克是否死亡
    public boolean isDead(){
        return this.blood<=0;
    }
    //坦克开始工作
    public void work(){
        this.state=TANK_GO;
    }
    //坦克重置
    public void reSet(){
        this.setX(-100);
        this.setY(-100);
        this.setBlood(TANK_MAX_BLOOD);
        this.setState(TANK_STOP);
    }
    public int getDirection() {
        return direction;
    }

    public void setDirection(int direction) {
        this.direction = direction;
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

    public int getSpeed() {
        return speed;
    }

    public void setSpeed(int speed) {
        this.speed = speed;
    }

    public int getBlood() {
        return blood;
    }

    public void setBlood(int blood) {
        this.blood = blood;
    }

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }

    public int getState() {
        return state;
    }

    public void setState(int state) {
        this.state = state;
    }

    public Vector<Bullet> getBullets() {
        return bullets;
    }

    public void setBullets(Vector<Bullet> bullets) {
        this.bullets = bullets;
    }
}
